<template>
  <div class="">
    <div class="content content--canvas"></div>
  </div>
</template>
 
<script>
import { floor, rand, randIn, randRange, fadeIn, fadeOut, fadeInOut, dist, angle, lerp, HALF_PI, TAU, TO_RAD } from './js/util.js'
const { PI, cos, sin, abs, sqrt, pow, round, random, atan2 } = Math;
export default {
  data () {
    return {
       canvas: {
        a: document.createElement('canvas'),
        b: document.createElement('canvas')
      },
      ctx: {
        a: null,
        b: null
      },
      center: [],
      particleCount: 700,
      particlePropCount: 9,
      particlePropsLength: 700 * 9,
      rangeY: 100,
      baseTTL: 50,
      rangeTTL: 150,
      baseSpeed: 0.1,
      rangeSpeed: 2,
      baseRadius: 1,
      rangeRadius: 4,
      baseHue: 220,
      rangeHue: 100,
      noiseSteps: 8,
      xOff: 0.00125,
      yOff: 0.00125,
      zOff: 0.0005,
      backgroundColor: 'hsla(260,40%,5%,1)',

      container: null,
      gradient: null,
      tick: null,
      simplex: null,
      particleProps: null,
    }
  },
  mounted() {
    // window.addEventListener('load', this.init());
    this.init()
    console.log(this.particlePropsLength)
  },
  methods: {
    init() {
      this.createCanvas()
      this.resize()
      this.initParticles()
      this.draw()
    },

    // 颗粒
    initParticles() {
      this.tick = 0;
      this.simplex = new SimplexNoise();
      this.particleProps = new Float32Array(this.particlePropsLength);
      // console.log(this.particleProps[9])
      let i;
      
      for (i = 0; i < this.particlePropsLength; i += this.particlePropCount) {
        this.initParticle(i);
      }
    },
    initParticle(i) {
      let x, y, vx, vy, life, ttl, speed, radius, hue;

      x = rand(this.canvas.a.width);
      y = this.center[1] + randRange(this.rangeY);
      vx = 0;
      vy = 0;
      life = 0;
      ttl = this.baseTTL + rand(this.rangeTTL);
      speed = this.baseSpeed + rand(this.rangeSpeed);
      radius = this.baseRadius + rand(this.rangeRadius);
      hue = this.baseHue + rand(this.rangeHue);

      this.particleProps.set([x, y, vx, vy, life, ttl, speed, radius, hue], i);
    },
    drawParticles() {
      let i;

      for (i = 0; i < this.particlePropsLength; i += this.particlePropCount) {
        this.updateParticle(i);
      }
    },
    randomNum(minNum,maxNum){ 
      switch(arguments.length){ 
        case 1: 
          return parseInt(Math.random()*minNum+1,10); 
        break; 
        case 2: 
          return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10); 
        break; 
          default: 
              return 0; 
          break; 
      } 
    },
    updateParticle(i) {
      let i2=1+i, i3=2+i, i4=3+i, i5=4+i, i6=5+i, i7=6+i, i8=7+i, i9=8+i;
      let n, x, y, vx, vy, life, ttl, speed, x2, y2, radius, hue;

      x = this.particleProps[i];
      y = this.particleProps[i2];
      n = this.simplex.noise3D(x * this.xOff, y * this.yOff, this.tick * this.zOff) * this.noiseSteps * TAU;
      vx = lerp(this.particleProps[i3], cos(n), 0.5);
      vy = lerp(this.particleProps[i4], sin(n), 0.5);
      life = this.particleProps[i5];
      ttl = this.particleProps[i6];
      speed = this.particleProps[i7];
      x2 = x + vx * speed;
      y2 = y + vy * speed;
      radius = this.particleProps[i8];
      // hue = this.particleProps[i9];
      let colors = [35, 207, 182]
      let colorsIndex = this.randomNum(0,2)
      hue = colors[colorsIndex]
      
      // console.log(hue)

      this.drawParticle(x, y, x2, y2, life, ttl, radius, hue);

      life++;

      this.particleProps[i] = x2;
      this.particleProps[i2] = y2;
      this.particleProps[i3] = vx;
      this.particleProps[i4] = vy;
      this.particleProps[i5] = life;

      (this.checkBounds(x, y) || life > ttl) && this.initParticle(i);
    },
    drawParticle(x, y, x2, y2, life, ttl, radius, hue) {
      this.ctx.a.save();
      this.ctx.a.lineCap = 'round';
      this.ctx.a.lineWidth = radius;
      this.ctx.a.strokeStyle = `hsla(${hue},100%,60%,${fadeInOut(life, ttl)})`;
      // this.ctx.a.strokeStyle = `hsla(35,100%,56%,${fadeInOut(life, ttl)})`;
      this.ctx.a.beginPath();
      this.ctx.a.moveTo(x, y);
      this.ctx.a.lineTo(x2, y2);
      this.ctx.a.stroke()
      this.ctx.a.closePath();
      this.ctx.a.restore();
    },

    checkBounds(x, y) {
      return(
        x > this.canvas.a.width ||
        x < 0 ||
        y > this.canvas.a.height ||
        y < 0
      );
    },

    createCanvas() {
      this.container = document.querySelector('.content--canvas');
      
        console.log(this.canvas)
        this.canvas.b.style = `
          position: relation;
          top: 0;
          left: 0;
          width: 100%;
          height: 500px;
        `;
        this.container.appendChild(this.canvas.b);
        this.ctx = {
          a: this.canvas.a.getContext('2d'),
          b: this.canvas.b.getContext('2d')
        };
    },

    resize() {
      // console.log(canvas)
      const { innerWidth, innerHeight } = window;
      
      this.canvas.a.width = innerWidth;
      this.canvas.a.height = innerHeight;

      this.ctx.a.drawImage(this.canvas.b, 0, 0);

      this.canvas.b.width = innerWidth;
      this.canvas.b.height = innerHeight;
      
      this.ctx.b.drawImage(this.canvas.a, 0, 0);

      this.center[0] = 0.5 * this.canvas.a.width;
      this.center[1] = 0.5 * this.canvas.a.height;
    },

    renderGlow() {
      this.ctx.b.save();
      this.ctx.b.filter = 'blur(8px) brightness(200%)';
      this.ctx.b.globalCompositeOperation = 'lighter';
      this.ctx.b.drawImage(this.canvas.a, 0, 0);
      this.ctx.b.restore();

      this.ctx.b.save();
      this.ctx.b.filter = 'blur(4px) brightness(200%)';
      this.ctx.b.globalCompositeOperation = 'lighter';
      this.ctx.b.drawImage(this.canvas.a, 0, 0);
      this.ctx.b.restore();
    },

    renderToScreen() {
      this.ctx.b.save();
      this.ctx.b.globalCompositeOperation = 'lighter';
      this.ctx.b.drawImage(this.canvas.a, 0, 0);
      this.ctx.b.restore();
    },

    draw() {
      this.tick++;

      this.ctx.a.clearRect(0, 0, this.canvas.a.width, this.canvas.a.height);

      const gradient = this.ctx.b.createLinearGradient(0, this.canvas.a.height, 0, 0)
      gradient.addColorStop(0, '#0E2244')
      gradient.addColorStop(1, '#1B3A67')
      // this.ctx.b.fillStyle = this.backgroundColor; 
      this.ctx.b.fillStyle = gradient; 
      this.ctx.b.fillRect(0, 0, this.canvas.a.width, this.canvas.a.height);

      this.drawParticles();
      this.renderGlow();
      this.renderToScreen();

      window.requestAnimationFrame(this.draw);
    }
  }
}
</script>
 